#include "stdafx.h"
#include "core.h"
#include "test.h"
#include <iostream> 

void test_string()
{
	{
		int a = 1<<5;
		int a1 = 'a'<<5;
		int a2 = ' '<<5;
		int a3 = 'A'<<5;
		int a4 = ']'<<5;

		std::cout<< "asdqwe  hash = "<< _strHash("asdqwe", 100)<< std::endl;
		std::cout<< "acg  hash = "<< _strHash("acg", 100)<< std::endl;
		std::cout<< "1234  hash = "<< _strHash("1234", 100)<< std::endl;
		std::cout<< "ger  hash = "<< _strHash("ger", 100)<< std::endl;
		std::cout<< "asdq  hash = "<< _strHash("asdq", 100)<< std::endl;
		std::cout<< "55  hash = "<< _strHash("55", 100)<< std::endl;
		std::cout<< "5555  hash = "<< _strHash("5555", 100)<< std::endl;
		std::cout<< "555555  hash = "<< _strHash("555555", 100)<< std::endl;
		std::cout<< "stan  hash = "<< _strHash("stan", 100)<< std::endl;
		std::cout<< "class  hash = "<< _strHash("class", 100)<< std::endl;
		std::cout<< "cout  hash = "<< _strHash("cout", 100)<< std::endl;
		std::cout<< "std  hash = "<< _strHash("std", 100)<< std::endl;
		std::cout<< "_strHash  hash = "<< _strHash("_strHash", 100)<< std::endl;
		std::cout<< "DString  hash = "<< _strHash("DString", 100)<< std::endl;
		std::cout<< "operator  hash = "<< _strHash("operator", 100)<< std::endl;
		std::cout<< "+  hash = "<< _strHash("+", 100)<< std::endl;

	}
	{
		DString str0;
		_check( str0 == 0);
		//std::cout<< (const char*)str0<< std::endl;
		DString str1("test str abcdef.");
		std::cout<< (const char*)str1<< std::endl;
		DString str2 = "test value2 str ghijk.";
		std::cout<< (const char*)str2<< std::endl;

		str0 = str1;
		str0 = "new value";
		std::cout<< "str0 = \"new value\""<< std::endl;
		std::cout<< "str0 = "<< str0 << std::endl;
		std::cout<< "str1 = "<< str1 << std::endl;
		
	}


	{
		DString test;
		test += "test";
		std::cout<< test<< std::endl;
		std::cout<< "test[0] = "<<test[0]<< std::endl;
		std::cout<< "test[1] = "<<test[1]<< std::endl;
		std::cout<< "test[2] = "<<test[2]<< std::endl;
		std::cout<< "test[3] = "<<test[3]<< std::endl;
	}

	{
		DString test;
		test.FormatSelf("fmt: int %d, float %f, str %s", 100, 0.5f, "string val");
		std::cout<< test<< std::endl;

		DString fmt =  DString::Format("fmt: int %d, float %f, str %s", 100, 0.5f, "string val");
		std::cout<< fmt<< std::endl;
	}

	
	{
		DString test;
		test += "1234567 890";
		std::cout<< test.Cmp( "1234567 890")<< std::endl;
		test = "abc";
		std::cout<< test.Cmp( "ABC")<< std::endl;
		std::cout<< test.ICmp( "ABC")<< std::endl;
	}

	{
		DString test = "1234567890";
		DString v1 = test.Sub( 0, 3);
		std::cout<< v1<< std::endl;
		DString v2 = test.Sub( 3, 6);
		std::cout<< v2<< std::endl;
		DString v3 = test.Sub( 6, 9);
		std::cout<< v3<< std::endl;


		s32_t pos = 0;
		DString v4 = test.Split( "31590", pos);
		while( v4 )
		{
			std::cout<< v4<< std::endl;

			v4 = test.Split( "31509", pos);
		}

	}

	{
		DString test = "1234567890";
		std::cout<< "find \"312\" pos = " <<test.Find("312")<< std::endl;;
		std::cout<< "FindFristOf \"369\" pos = " <<test.FindFristOf("369")<< std::endl;;
		std::cout<< "FindFristOf DString() pos = " <<DString().FindFristOf("369")<< std::endl;;
	}

	{
		DString test = "1234567890";
		test.Replace( "456", "ABC");
		std::cout<< test<< std::endl;
	}

	{
		DString test = "abcdef ABCDEF";
		DString val0 = test;
		val0.Upper();
		std::cout<< val0<< std::endl;
		
		val0 = test;
		val0.Lower();
		std::cout<< val0<< std::endl;
	}


	{
		DString test9 = "999999";
		DString test = "abcdef ABCDEF ";
		test += test9;
		test += test;
		test += test9;
		test += test9;
		test += test9;
		test += test9;
		test += test9;
		test += test9;
		test += test9;
		test += test9;
		test += test9;
		test.Cat( test);
		test.Cat( "abcdef");
		test.Cat( "  ");
		test.Cat( test);
		test.Cat( test9);
		std::cout<< test<< std::endl;
	}

	{
		DString test9 = "999999";
		std::cout<< test9<< std::endl;
		
		DString test = test9;
		std::cout<< test<< std::endl;
		
		test = '6';
		std::cout<< test<< std::endl;
		
		test += '6';
		std::cout<< test<< std::endl;
		
		test += DString(" 9023f");
		std::cout<< test<< std::endl;
		
		test += "asdfo";
		std::cout<< test<< std::endl;
	}


	{
		DString a_test = "abcd";
		DString a_test2 = "abcd2";
		const char* c_test = "abcd";
		const char* c_test2 = "abcd2";

		std::cout<< (a_test == a_test2)<< std::endl;
		std::cout<< (a_test != a_test2)<< std::endl;
		std::cout<< (a_test == c_test)<< std::endl;
		std::cout<< (a_test != c_test2)<< std::endl;

		std::cout<< (c_test == a_test) << std::endl;
		std::cout<< (c_test2 == a_test) << std::endl;


		std::cout<< (c_test + a_test) << std::endl;
		std::cout<< (a_test + a_test) << std::endl;
		std::cout<< (a_test + 'a') << std::endl;
		std::cout<< (a_test + c_test) << std::endl;

	}
}

void test_vector()
{
	std::cout<< "test_vector()"<< std::endl;
	TArray<s32_t> ary0;
	ary0.Add(1);
	ary0.Add(1);
	ary0.Add(1);
	ary0.Add(1);
	ary0.Add(5);
	ary0.Pop();

	TArray<DString> ary(6);
	ary[0] = "1";
	ary[1] = "2";
	ary[1] += ary[1];

	ary[2] = "2";
	ary[2] += ary[1] + ary[0];
	ary[3] = "3";
	ary[4] = "4";
	ary[5] = "5";
	for( s32_t i = 0 ; i < 6; ++i)
	{
		std::cout<< ary[i]<< std::endl;
	}

	std::cout<< ary.Num()<< std::endl;

	s32_t outIndex = null_index;
	std::cout<< ary.Find( "4", outIndex)<< std::endl;
	std::cout<< outIndex<< std::endl;
	std::cout<< ary.FindIndex( "4")<<std::endl;
	std::cout<< ary.Add( "last value")<< std::endl;
	std::cout<< ary.Last()<< std::endl;
	std::cout<< ary.Num()<< std::endl;
	std::cout<< "ary.AddUnique( \"last value\")  " <<  ary.AddUnique( "last value")<< std::endl;
	std::cout<< ary.Num()<< std::endl;
	std::cout<< ary.Pop()<< std::endl;
	std::cout<< ary.Num()<< std::endl;
	std::cout<< "-------------"<< std::endl;
	std::cout<< ary.Remove("4")<< std::endl;
	std::cout<< ary.Num()<< std::endl;
	std::cout<< ary.FindIndex( "4")<<std::endl;

	TArray<DString> aryCpy = ary;

	std::cout<< "-------------"<< std::endl;
	std::cout<< ary.Num() <<" "<< ary.BufCap()<< std::endl;
	ary.Shrink();
	std::cout<< ary.Num() <<" "<< ary.BufCap()<< std::endl;
	ary.Clear();
	std::cout<< ary.Num() <<" "<< ary.BufCap()<< std::endl;


	std::cout<< "-------------"<< std::endl;
	std::cout<< "-------------"<< std::endl;
	std::cout<< aryCpy.Num() <<" "<< aryCpy.BufCap()<< std::endl;
	{
		TArray<DString>::Iterator it( aryCpy);

		while( it)
		{
			std::cout<< it.Index()<< ": "<< *it << std::endl;
			it.Next();
		}

	}
	std::cout<< "-------------"<< std::endl;

	{
		TArray<DString>::Iterator it2( aryCpy);
		for( s32_t i = 0; i <2;++i)
		{
			it2.Next();
		}
		std::cout<< it2.Index()<< ": "<< *it2<< std::endl;
		it2.RemoveCurrent();
		std::cout<< it2.Index()<< ": "<< *it2 << std::endl;
	}
	std::cout<< "-------------"<< std::endl;

	{
		TArray<DString>::Iterator it( aryCpy);

		while( it)
		{
			std::cout<< it.Index()<< ": "<< *it << std::endl;
			it.Next();
		}
	}
}

template< class TKey, class TVal>
void DumpMap( TMap< TKey, TVal> & map)
{
	std::cout<< "------Map------"<< std::endl;
	std::cout<< "HashCount = "<< map.mHashCount <<", Items Num= "<< map.Num()<< std::endl;
	if( map.Num())
	{
		for( s32_t i = 0 ; i < map.mHashCount; ++i)
		{
			s32_t id = map.mHashIndex[i];
			if( id != null_index)
				std::cout<<"**Hash value="<< i<<" item list:"<<std::endl;
			while( id != null_index)
			{
				TMap< TKey, TVal>::Pair pair = map.mPairs[ id];
				std::cout<< "Item["<< id<< "],Key:"<< pair.Key
					<< ", Val:"<< pair.Val<< ", Next:"<< pair.Next<< std::endl;
				id = pair.Next;
			}
		}
	}
}


void test_map()
{
	TMap< SString, DString> testMap;
	testMap.Set("test","test");
	DumpMap( testMap);
	testMap.Set("SString","test2");
	testMap.Set("return","test2");
	testMap.Set("for","test2");
	testMap.Set("id","test2");
	testMap.Set("test","test2");
	testMap.Set("Dump","jdfg");
	testMap.Set("TVal","dfgj");
	testMap.Set("testS","dgj");
	testMap.Set("test_name","367");
	testMap.Set("1","2");
	testMap.Set("3","4");
	testMap.Set("test_name","4");
	testMap.Set("StaticInit","46");
	testMap.Set(".","dj");
	testMap.Set(".","3567");
	testMap.Set("sh%mo","4");
	testMap.Set("name",",6");
	testMap.Set("basic_ostream","536");
	testMap.Set("namea","qwer");
	testMap.Set("4","qwe1");
	testMap.Set("pair","awewq");
	testMap.Set("testMap","Set");
	testMap.Set("InValue","Set");
	testMap.Set("testMap","InKey");
	testMap.Set("DumpMap","InKey");
	testMap.Set("cout","InKey");
	testMap.Set("#define","InKey");
	testMap.Set("#void","InKey");
	testMap.Set("CoreShutdown","InKey");
	testMap.Set("asdfppSasdwetrheqash","InKey");
	DumpMap( testMap);
	
	testMap.Remove("asdfppSasdwetrheqash");
	testMap.Remove("InValue");
	testMap.Remove(".");
	testMap.Remove(".");
	testMap.Remove("#define");
	testMap.Remove("return");
	testMap.Remove("");
	testMap.Remove("SString");
	testMap.Remove("return");
	testMap.Remove("id");
	testMap.Remove("for");
	testMap.Remove("testS");
	testMap.Remove("4");
	testMap.Remove("test_name");
	testMap.Remove("#void");
	testMap.Remove("namea");
	testMap.Remove("pair");
	testMap.Remove("define");
	testMap.Remove("InValue");
	testMap.Remove("CoreShutdown");
	testMap.Remove("cout");
	testMap.Remove("DumpMap");
	testMap.Remove("testMap");
	testMap.Remove("StaticInit");
	DumpMap( testMap);
	testMap.Set("CoreShutdown","InKey");
	testMap.Set("testMap","Set");

	TMap< SString, DString> testMap3 = testMap;
	testMap3.Clear();
	DumpMap( testMap);

	TMap< SString, DString> testMap2 = testMap;
	{
		TMap< SString, DString>::Iterator it2( testMap2);

		while( it2)
		{
			_check( testMap.Find( it2.Key()));

			DString& val = it2.Val();
			std::cout<< val<<std::endl;
			testMap.Remove( it2.Key());
			it2.RemoveCurrent();
			it2.MoveNext();
		}
	}

	DumpMap( testMap2);
	DumpMap( testMap);

	TMap< s32_t , DString> numKeyMap;
	for( s32_t i = 0 ; i < 38;++i)
	{
		DString val = DString::Format("map item val = %d", i);
		numKeyMap.Set( i, val);
	}
	DumpMap( numKeyMap);

}

void test_name()
{

	SString namea;
	SString name = "name0";
	SString name2 = "name0";
	SString name3 = "name new";

	DString testS = namea;
	DString testS1( namea);
	DString testS2( name);

	namea = testS;
	namea = testS1;
	SString name6 = testS2;

	_check( testS2 == name6);
	_check( name6 == testS2);

	std::cout<< name<< std::endl;
	std::cout<< name2<< std::endl;
	std::cout<< name3<< std::endl;

	std::cout<< "test_name()"<< std::endl;

	_check( name == name2);
	_check( name == "name0");
	_check( name != name3);
	_check( name != "name any");
}

void go_test()
{
	CoreInit();
	
	test_string();
	test_vector();
	test_name();
	test_map();
	
	CoreShutdown();
	
}

/*
void go_test()
{
	CoreInit();

	test_string();
	test_vector();

	CoreShutdown();

}
*/